package cn.sll.base.service.impl;

import cn.sll.base.util.StrUtils;
import cn.sll.base.cons.PhoneRegisterCons;
import cn.sll.base.service.VerifyCodeService;
import cn.sll.base.util.BussinessException;
import cn.sll.base.util.VerifyCodeUtils;
import cn.sll.org.dto.SmsDto;
import cn.sll.org.dto.SmsRegisterDto;
import cn.sll.user.domain.Logininfo;
import cn.sll.user.domain.User;
import cn.sll.user.service.ILogininfoService;
import cn.sll.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserService userService;

    @Autowired
    private ILogininfoService logininfoService;

    //图片验证码
    @Override
    public String imageCode(String imageCodeKey) throws IOException {
        // 参数校验
        //生成随机字符
        String randomString = StrUtils.getRandomString(4);
        // redis存储
        redisTemplate.opsForValue().set(imageCodeKey,randomString,3, TimeUnit.MINUTES);
        // 返回生成图片base64编码
        return VerifyCodeUtils.VerifyCode(80,30,randomString);
    }

    //手机验证码
    @Override
    public void smsCode(SmsDto smsDto) {
        if ("binder".equals(smsDto.getType())){
            // 发送短信
            this.sendSms(PhoneRegisterCons.BINDER_KEY,smsDto);
        }else if ("register".equals(smsDto.getType())){
            // 图形验证码验证
            this.imageVerify(smsDto);
            // 发送短信
            this.sendSms(PhoneRegisterCons.REDIS_KEY,smsDto);
        }

    }

    //手机验证码注册
    @Override
    public void smsRegister(SmsRegisterDto dto) {
        //参数校验

        //手机验证码是否过期是否存在
        String smsPhoneValue = (String) redisTemplate.opsForValue().get(String.format(PhoneRegisterCons.REDIS_KEY,dto.getPhone()));
        log.info(smsPhoneValue);
        if (StringUtils.isBlank(smsPhoneValue) || !smsPhoneValue.equalsIgnoreCase(dto.getSmsPhoneValue())){
            throw new BussinessException("手机验证码有误！");
        }
        //判断2次密码是否正确
        if(!dto.getPassword().equals(dto.getPasswordRepeat())){
            throw new BussinessException("二次密码不一致！");
        }

        //手机号是否存在
        User user = userService.findByPhone(dto.getPhone());
        if (user != null){
            throw new BussinessException("该手机已注册");
        }

        //保存数据，user 和 logininfo
        user = dto.getUser();
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setType(1);
        logininfo.setDisable(true);
        logininfoService.add(logininfo);
        user.setLogininfoId(logininfo.getId());
        userService.add(user);

    }

    private void sendSms(String redisKey,SmsDto smsDto) {
        //两次发送时间是否大于60s
        Long expire = redisTemplate.getExpire(String.format(redisKey,smsDto.getPhone()));
        if (null != expire && expire > 120L && expire!=null){
            throw new BussinessException("60秒不要发送");
        }

        // 是否需要重置手机验证码
        // 如果redis中不存在验证码 1.第一次来  2.过期了
        String phoneValue = (String) redisTemplate.opsForValue().get(String.format(redisKey,smsDto.getPhone()));
        if(StringUtils.isBlank(phoneValue)){
            //生成新的验证码
            phoneValue  = VerifyCodeUtils.generateVerifyCode(4);
        }
        log.info("手机验证码：{}",phoneValue);

        //将验证码存到redis中
        redisTemplate.opsForValue().set(String.format(redisKey,smsDto.getPhone()),phoneValue,3,TimeUnit.MINUTES);

        //发送手机验证码
//        SendSms.sendsms("sl1255535829",
//                "1F4F498C16B1749EA68B8979E590944D",
//                "18381097061",
//                phoneValue);
    }

    private void imageVerify(SmsDto smsDto) {

        // 校验参数

        // 判断图形验证码是否存在是否正确
        String imageValue = (String) redisTemplate.opsForValue().get(smsDto.getImageCodeKey());
        if(!smsDto.getImageCodeValue().equals(imageValue) || imageValue == null){
            throw new BussinessException("图片验证码有误！");
        }
        //判断手机号是否注册过
        User user = userService.findByPhone(smsDto.getPhone());
        if (user != null){
            throw new BussinessException("该手机已注册");
        }

        //删除图形验证码
        redisTemplate.delete(smsDto.getImageCodeKey());

    }
}
